<template>
  <div>
    <div class="p-6 max-w-5xl mx-auto">
      <div class="flex justify-between items-center mb-4">
        <h1 class="text-2xl font-bold text-gray-800">问题详情</h1>
        <router-link v-if="!embedded" to="/issues" class="text-blue-600">返回列表</router-link>
      </div>

      <div v-if="!issue" class="text-gray-500">加载中...</div>
      <div v-else class="grid md:grid-cols-3 gap-6">
        <div class="md:col-span-2 space-y-4">
          <div class="bg-white rounded shadow p-4">
            <div class="flex items-start justify-between mb-2">
              <h2 class="text-xl font-semibold text-gray-800">{{ issue.title }}</h2>
              <span :class="badgeClass(issue.priority)">{{ issue.priority }}</span>
            </div>
            <div class="text-gray-700 prose max-w-none" v-if="issue.description" v-html="issue.description"></div>
            <p v-else class="text-gray-500">无描述</p>
          </div>

          <div class="bg-white rounded shadow p-4">
            <h3 class="font-semibold mb-3">处理步骤</h3>
            <ul class="space-y-2">
              <li v-for="s in issue.steps" :key="s.id" class="flex items-center gap-3">
                <input type="checkbox" v-model="s.done" @change="updateStep(s)" />
                <span :class="['text-sm', s.done ? 'line-through text-gray-400' : 'text-gray-700']">{{ s.content }}</span>
              </li>
            </ul>

            <div class="mt-4 flex gap-2">
              <input v-model="newStep" class="border rounded px-3 py-2 flex-1" placeholder="新增步骤..." />
              <button class="bg-blue-600 text-white px-4 py-2 rounded" @click="addStep">添加</button>
            </div>
          </div>
        </div>

        <div class="space-y-4">
          <div class="bg-white rounded shadow p-4">
            <h3 class="font-semibold mb-3">属性</h3>
            <div class="space-y-2 text-sm text-gray-700">
              <div>状态：{{ statusText(issue.status) }}</div>
              <div>所在目录：{{ issueFolderPath }}</div>
              <div>截止时间：{{ issue.deadline ? new Date(issue.deadline).toLocaleString() : '-' }}</div>
              <div>创建时间：{{ new Date(issue.created_at).toLocaleString() }}</div>
              <div>更新：{{ new Date(issue.updated_at).toLocaleString() }}</div>
            </div>
          </div>

          <div class="bg-white rounded shadow p-4">
            <h3 class="font-semibold mb-3">操作</h3>
            <div class="flex flex-wrap gap-2">
              <button class="px-3 py-2 border rounded" @click="setStatus('doing')">开始处理</button>
              <button class="px-3 py-2 border rounded" @click="setStatus('verify')">提交验证</button>
              <button class="px-3 py-2 border rounded" @click="setStatus('done')">标记完成</button>
              <button class="px-3 py-2 border rounded" @click="setStatus('done')">标记完成</button>
              <button class="px-3 py-2 border rounded" @click="openLinkKnowledge">添加到知识点</button>
              <button class="px-3 py-2 border rounded" @click="openEdit">编辑</button>
              <button class="px-3 py-2 border rounded text-red-600" @click="removeIssue">删除</button>
              <button class="px-3 py-2 border rounded" @click="openMove">移动到目录</button>
              <button class="px-3 py-2 border rounded" @click="exportMarkdown">导出为 Markdown</button>
            </div>
          </div>
        </div>
        <!-- Edit Dialog -->
        <div v-if="showEdit" class="fixed inset-0 z-50 bg-black/50 flex items-center justify-center p-4">
          <div class="bg-white rounded-lg shadow-2xl ring-1 ring-black/5 w-full max-w-2xl p-6">
            <h2 class="text-lg font-semibold mb-4">编辑问题</h2>
            <div class="space-y-3">
              <input v-model="editForm.title" class="border rounded px-3 py-2 w-full" placeholder="标题*" />
              <div class="space-y-2">
                <RichTextEditor v-model="editForm.description" :height="360" @ready="editorReady = true" />
              </div>
              <div class="grid md:grid-cols-3 gap-3">
                <select v-model="editForm.priority" class="border rounded px-3 py-2">
                  <option value="P0">紧急</option>
                  <option value="P1">高</option>
                  <option value="P2">中</option>
                  <option value="P3">低</option>
                </select>
                <input v-model="editForm.deadline" type="datetime-local" class="border rounded px-3 py-2" />
              </div>
            </div>
            <div class="mt-6 flex justify-end gap-3">
              <button class="px-4 py-2 border rounded" @click="showEdit = false">取消</button>
              <button class="px-4 py-2 bg-blue-600 text-white rounded" @click="submitEdit">保存</button>
            </div>
          </div>
        </div>

        <!-- Link Knowledge Dialog -->
        <div v-if="showLinkK" class="fixed inset-0 bg-black/50 flex items-center justify-center p-4 z-50">
          <div class="bg-white rounded-lg shadow-2xl ring-1 ring-black/5 w-full max-w-4xl h-[80vh] flex flex-col">
            <div class="px-6 py-4 border-b flex justify-between items-center">
              <h2 class="text-lg font-semibold">添加到知识点</h2>
              <button @click="showLinkK = false" class="text-gray-500 hover:text-gray-700">&times;</button>
            </div>
            
            <div class="flex-1 flex overflow-hidden">
              <!-- Left: Folder Tree -->
              <div class="w-1/3 border-r flex flex-col">
                <div class="p-2 bg-gray-50 font-medium border-b">1. 选择目录</div>
                <div class="flex-1 overflow-auto p-2">
                  <KnowledgeFolderTree @select="onLinkKFolderSelect" />
                </div>
              </div>

              <!-- Middle: Knowledge List -->
              <div class="w-1/3 border-r flex flex-col">
                <div class="p-2 bg-gray-50 font-medium border-b">2. 选择知识点</div>
                <div class="p-2 border-b">
                  <input v-model="kKeyword" class="w-full border rounded px-2 py-1" placeholder="搜索知识点..." @input="loadKnowledgeList" />
                </div>
                <div class="flex-1 overflow-auto p-2 space-y-1">
                  <div v-for="k in kList" :key="k.id" 
                       class="cursor-pointer px-3 py-2 rounded hover:bg-gray-100 border border-transparent"
                       :class="{ 'bg-blue-50 border-blue-200 text-blue-700': selectedKnowledgeId === k.id }"
                       @click="selectedKnowledgeId = k.id">
                    <div class="font-medium truncate">{{ k.title }}</div>
                    <div class="text-xs text-gray-500 truncate">{{ new Date(k.created_at).toLocaleString() }}</div>
                  </div>
                  <div v-if="kList.length === 0" class="text-gray-400 text-center mt-4">无知识点</div>
                </div>
              </div>

              <!-- Right: Preview/Confirm -->
              <div class="w-1/3 flex flex-col bg-gray-50 p-4">
                <div class="font-medium mb-4">3. 确认添加</div>
                <div class="flex-1 overflow-auto space-y-4">
                  <div v-if="selectedKnowledgeId">
                    <div class="text-sm text-gray-600 mb-1">将添加到：</div>
                    <div class="font-bold text-gray-800 bg-white p-2 rounded border">
                      {{ kList.find(k => k.id === selectedKnowledgeId)?.title }}
                    </div>
                  </div>
                  <div v-else class="text-gray-400 text-sm">请先在左侧选择一个知识点</div>
                  
                  <div class="border-t pt-4 mt-4">
                    <div class="text-sm text-gray-600 mb-1">将生成的问题卡片：</div>
                    <div class="bg-white p-3 rounded border text-sm space-y-2">
                      <div><span class="font-semibold">问题：</span>{{ issue.title }}</div>
                      <div><span class="font-semibold">答案：</span>(问题描述)</div>
                    </div>
                  </div>
                </div>
                
                <div class="mt-4 flex gap-2">
                  <button class="flex-1 border bg-white py-2 rounded hover:bg-gray-50" @click="showLinkK = false">取消</button>
                  <button class="flex-1 bg-blue-600 text-white py-2 rounded hover:bg-blue-700 disabled:opacity-50"
                          :disabled="!selectedKnowledgeId"
                          @click="submitLinkKnowledge">
                    确定添加
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- Move Dialog -->
        <div v-if="showMove" class="fixed inset-0 bg-black/50 flex items-center justify-center p-4">
          <div class="bg-white rounded-lg shadow-2xl ring-1 ring-black/5 w-full max-w-sm p-6">
            <h2 class="text-lg font-semibold mb-4">移动到目录</h2>
            <div class="space-y-3">
              <select v-model="moveFolderId" class="border rounded px-3 py-2 w-full">
                <option :value="null">（无）</option>
                <option v-for="f in folderOptions" :key="f.id" :value="f.id">{{ f.label }}</option>
              </select>
            </div>
            <div class="mt-6 flex justify-end gap-3">
              <button class="px-4 py-2 border rounded" @click="showMove=false">取消</button>
              <button class="px-4 py-2 bg-blue-600 text-white rounded" @click="confirmMove">确定</button>
            </div>
          </div>
        </div>
        <!-- Summary Section -->
        <div class="md:col-span-3">
          <div class="bg-white rounded shadow p-4">
            <div class="flex items-center justify-between mb-2">
              <h3 class="font-semibold">问题总结</h3>
              <div class="text-sm text-gray-600 flex items-center gap-3">
                <button class="px-2 py-1 border rounded" @click="saveSummary">保存</button>
              </div>
            </div>
            <div>
              <RichTextEditor v-model="summaryHtml" :height="260" @ready="sumReady = true" />
            </div>
            <div class="mt-4 text-gray-700 prose max-w-none" v-if="summaryHtml" v-html="summaryHtml"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, computed, nextTick, watch, onBeforeUnmount, defineExpose } from 'vue'
import { useRoute } from 'vue-router'
import api from '../api'
import { useFolderStore } from '../stores/folders'
import { useKnowledgeFolderStore } from '../stores/knowledgeFolders'
import KnowledgeFolderTree from '../components/KnowledgeFolderTree.vue'
import RichTextEditor from '../components/RichTextEditor.vue'

const route = useRoute()
const props = defineProps({ issueId: { type: [String, Number], default: null }, embedded: { type: Boolean, default: false } })
const currentId = computed(() => props.issueId ?? route.params.id)
const issue = ref(null)
const newStep = ref('')
const showEdit = ref(false)
watch(showEdit, (v) => { try { document.body.style.overflow = v ? 'hidden' : '' } catch {} })
watch(showEdit, (v) => { if (!v) { editorReady.value = false } })
onBeforeUnmount(() => {})
const editForm = ref({ title: '', description: '', status: 'todo', priority: 'P2', deadline: '' })
// Edit editor states (rich text only)
const editorReady = ref(false)
const folderStore = useFolderStore()
const kFolderStore = useKnowledgeFolderStore()
const showLinkK = ref(false)
const linkKForm = ref({ title: '', summary: '', body: '' })

const badgeClass = (p) => {
  const map = { P0: 'bg-red-100 text-red-600 px-2 py-1 rounded text-xs', P1: 'bg-yellow-100 text-orange-600 px-2 py-1 rounded text-xs', P2: 'bg-blue-100 text-blue-600 px-2 py-1 rounded text-xs', P3: 'bg-gray-100 text-gray-600 px-2 py-1 rounded text-xs' }
  return map[p] || map.P2
}
const statusText = (s) => ({ todo: '待处理', doing: '处理中', verify: '待验证', done: '已解决' }[s] || s)

const issueFolderPath = computed(() => {
  const fid = issue.value?.folder_id
  if (fid == null) return '（无）'
  const map = new Map(folderStore.flat.map(f => [f.id, f]))
  const path = []
  let cur = map.get(fid)
  while (cur) { path.unshift(cur.name); cur = cur.parent_id ? map.get(cur.parent_id) : null }
  return path.join(' / ')
})

// Shared normalize function for HTML comparison - REMOVED as it caused inconsistency
// const normalizeHtml = (html) => { ... }

const load = async () => {
  const id = currentId.value
  const res = await api.get(`/api/issues/${id}`)
  issue.value = res.data
  
  // Don't set summaryHtml here, wait for editor to be ready
  // This prevents TinyMCE from modifying the content before we can save the original value
  
  await nextTick(); try { window.Prism && window.Prism.highlightAll() } catch {}
}

const setStatus = async (status) => {
  const id = currentId.value
  await api.put(`/api/issues/${id}`, { status })
  await load()
}

const addStep = async () => {
  if (!newStep.value) return
  const id = currentId.value
  await api.post(`/api/issues/${id}/steps`, { content: newStep.value, done: false })
  newStep.value = ''
  await load()
}

const updateStep = async (s) => {
  const id = currentId.value
  await api.put(`/api/issues/${id}/steps/${s.id}`, { content: s.content, done: s.done })
}

const toKnowledge = async () => {
  const id = currentId.value
  const r = await api.post(`/api/issues/${id}/to-knowledge`)
  alert(`已转为知识条目：#${r.data.knowledge_id}`)
  try { await kFolderStore.load() } catch {}
}

const kFolderId = ref(null)
const kKeyword = ref('')
const kList = ref([])
const selectedKnowledgeId = ref(null)

const onLinkKFolderSelect = (id) => {
  kFolderId.value = id
  loadKnowledgeList()
}

const loadKnowledgeList = async () => {
  const res = await api.get('/api/knowledge/', { params: { folder_id: kFolderId.value || undefined } })
  const all = res.data || []
  const q = (kKeyword.value || '').trim().toLowerCase()
  kList.value = q ? all.filter(x => x.title.toLowerCase().includes(q)) : all
}
const openLinkKnowledge = async () => {
  selectedKnowledgeId.value = null
  kKeyword.value = ''
  kFolderId.value = null
  await kFolderStore.load()
  loadKnowledgeList() // load root/all initially
  showLinkK.value = true
}
const submitLinkKnowledge = async () => {
  const id = currentId.value
  if (!selectedKnowledgeId.value) return
  
  try {
    await api.post(`/api/knowledge/${selectedKnowledgeId.value}/add_card_from_issue`, { issue_id: Number(id) })
    showLinkK.value = false
    alert('已添加为知识卡片')
    try { await kFolderStore.load() } catch {}
  } catch (e) {
    alert('添加失败')
  }
}

const openEdit = async () => {
  editForm.value = { title: issue.value.title, description: issue.value.description || '', status: issue.value.status, priority: issue.value.priority, deadline: issue.value.deadline ? issue.value.deadline.slice(0,16) : '' }
  showEdit.value = true
}
const submitEdit = async () => {
  const id = currentId.value
  // collect description (rich text only)
  const description = editForm.value.description
  await api.put(`/api/issues/${id}`, { title: editForm.value.title, description, priority: editForm.value.priority, deadline: editForm.value.deadline || null })
  showEdit.value = false
  await load()
}
const removeIssue = async () => {
  if (!confirm('确认删除该问题？')) return
  const id = currentId.value
  await api.delete(`/api/issues/${id}`)
  history.back()
}
const showMove = ref(false)
const moveFolderId = ref(null)
const folderOptions = computed(() => {
  const map = new Map(folderStore.flat.map(f => [f.id, f]))
  const depth = (f) => { let d=0, c=f; while (c?.parent_id) { d++; c = map.get(c.parent_id) } return d }
  return folderStore.flat.map(f => ({ id: f.id, label: `${'\u00A0'.repeat(depth(f)*2)}${f.name}` }))
})
const openMove = async () => {
  await folderStore.load()
  moveFolderId.value = issue.value?.folder_id ?? null
  showMove.value = true
}
const confirmMove = async () => {
  const { id } = route.params
  await api.put(`/api/issues/${id}`, { folder_id: moveFolderId.value })
  showMove.value = false
  await load()
}

onMounted(async () => { await folderStore.load(); await kFolderStore.load(); await load(); await initSummaryPrism() })

// Prism loader for code highlight used in preview
const sumReady = ref(false)
const summaryHtml = ref('')
const lastSavedSummary = ref('')
const summaryInitialized = ref(false)

// Watch for editor ready and set initial content
watch(sumReady, (ready) => {
  if (ready && !summaryInitialized.value && issue.value) {
    // Editor is ready, set the content if it hasn't been set yet
    summaryInitialized.value = true
    const content = issue.value?.summary || ''
    summaryHtml.value = content
    lastSavedSummary.value = content // Store raw content
  }
  // 允许后续的内容更新
})

// Watch for content changes to update lastSavedSummary when saving
watch(summaryHtml, (newVal) => {
  // 不需要在这里处理，让用户可以正常输入
})
const loadScript = (src) => new Promise((resolve, reject) => {
  if (document.querySelector(`script[src="${src}"]`)) return resolve()
  const s = document.createElement('script'); s.src = src; s.onload = resolve; s.onerror = reject; document.body.appendChild(s)
})
const loadCss = (href) => new Promise((resolve) => {
  if (document.querySelector(`link[href="${href}"]`)) return resolve()
  const l = document.createElement('link'); l.rel = 'stylesheet'; l.href = href; l.onload = resolve; document.head.appendChild(l)
})
const initSummaryPrism = async () => {
  await loadCss('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-markup.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-css.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-clike.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-javascript.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-typescript.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-jsx.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-tsx.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-java.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-kotlin.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-swift.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-python.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-go.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-rust.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-c.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-cpp.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-csharp.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-php.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-ruby.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-dart.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-bash.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-powershell.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-sql.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-json.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-yaml.min.js')
  await loadScript('https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-xml-doc.min.js')
}
const saveSummary = async () => {
  // prepare HTML content (rich text only)
  const content = summaryHtml.value || ''
  // persist to backend and refresh
  const id = currentId.value
  await api.post(`/api/issues/${id}/summaries`, null, { params: { content } })
  // 更新 issue 数据
  const res = await api.get(`/api/issues/${id}`)
  issue.value = res.data
  // 直接更新 lastSavedSummary，不需要重新加载整个页面
  lastSavedSummary.value = summaryHtml.value || '' // Store raw content
  try { window.Prism && window.Prism.highlightAll() } catch {}
}

// Expose dirty check for parent (Issues.vue) to prevent accidental close
const isSummaryDirty = () => {
  try {
    const current = summaryHtml.value || ''
    const saved = lastSavedSummary.value || ''
    
    // If both are empty, not dirty
    if (!current.trim() && !saved.trim()) return false
    
    // Debug: Log the actual values to see what's different
    console.log('Current:', JSON.stringify(current))
    console.log('Saved:', JSON.stringify(saved))
    
    // More aggressive normalization to handle TinyMCE's automatic additions
    const normalize = (html) => {
      return (html || '')
        .replace(/\s+/g, ' ') // Replace multiple spaces with single space
        .replace(/>\s+</g, '><') // Remove whitespace between tags
        .replace(/\s+\/>/g, '/>') // Remove whitespace before self-closing tags
        .replace(/data-mce-[a-z-]+="[^"]*"/gi, '') // Remove TinyMCE specific attributes
        .replace(/<meta[^>]*>/gi, '') // Remove meta tags
        .replace(/<link[^>]*>/gi, '') // Remove link tags
        .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '') // Remove style tags
        .replace(/class="[^"]*"/gi, '') // Remove class attributes
        .replace(/style="[^"]*"/gi, '') // Remove style attributes
        .replace(/data-[^=]*="[^"]*"/gi, '') // Remove all data attributes
        .replace(/<!--[\s\S]*?-->/g, '') // Remove HTML comments
        .replace(/&nbsp;/g, ' ') // Replace non-breaking space
        .trim()
    }
    
    const normalizedCurrent = normalize(current)
    const normalizedSaved = normalize(saved)
    
    // console.log('Normalized Current:', JSON.stringify(normalizedCurrent))
    // console.log('Normalized Saved:', JSON.stringify(normalizedSaved))
    
    return normalizedCurrent !== normalizedSaved
  } catch { return false }
}
defineExpose({ isSummaryDirty })

// Export Markdown
const exportMarkdown = () => {
  const md = `# ${issue.value.title}\n\n- 状态: ${statusText(issue.value.status)}\n- 优先级: ${issue.value.priority}\n- 截止: ${issue.value.deadline ? new Date(issue.value.deadline).toLocaleString() : '-'}\n\n## 描述\n\n${htmlToMarkdown(issue.value.description || '')}`
  const blob = new Blob([md], { type: 'text/markdown;charset=utf-8' })
  const a = document.createElement('a')
  a.href = URL.createObjectURL(blob)
  a.download = `issue-${issue.value.id}.md`
  a.click()
  URL.revokeObjectURL(a.href)
}
const htmlToMarkdown = (html) => {
  // very naive conversion for basic formatting
  return (html || '')
    .replace(/<\/?strong>|<\/?b>/g, '**')
    .replace(/<\/?em>|<\/?i>/g, '*')
    .replace(/<br\s*\/?>(?=_)/g, '\n')
    .replace(/<ul>/g, '\n')
    .replace(/<li>/g, '- ')
    .replace(/<\/(li|ul|p)>/g, '\n')
    .replace(/<[^>]+>/g, '')
}
</script>

<style>
@import "https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css";
/* Ensure lists and tables render clearly in v-html content */
.prose ul { list-style-type: disc; padding-left: 1.25rem; }
.prose ol { list-style-type: decimal; padding-left: 1.25rem; }
.prose table { width: 100%; border-collapse: collapse; margin: 0.5rem 0; }
.prose th, .prose td { border: 1px solid #e5e7eb; padding: 0.5rem; }
.prose thead th { background-color: #f9fafb; }
</style>
